/*
 * Jenny Ruppen 09-730-391
 * Sebastien Goldberg 08-914-855
 * Henry Raymond 08-928-061
 * Stefan Mussato 09-752-270
 */
 
package ch.uzh.ifi.sopra.gruppe9.game;

import java.util.ArrayList;

import ch.uzh.ifi.sopra.gruppe9.game.Scenery.Location;

import com.jme3.scene.Node;


/**
 * Interactive in-game screen of the tower element market.
 */
public class TowerElementMarketInterface extends Node {
	
	
	/**
	 * List of all registered mouseOver event elements of the tower element market.
	 */
	private ArrayList<IMouseOverable> mouseOverables = new ArrayList<IMouseOverable>();
	
	
	/**
	 * List of all registered click event elements of the tower element market.
	 */
	private ArrayList<IClickable> clickables = new ArrayList<IClickable>();
	
	
	/**
	 * The four tab buttons of the four markets.
	 */
	private GuiTabButton[] marketTabButtons = new GuiTabButton[4];
	
	
	/**
	 * Geometry node of all content of the window.
	 */
	private Node towerElementMarket;
	
	
	/**
	 * The four geometry nodes of the content of the four markets.
	 */
	private Node[] marketTab = new Node[4];
	
	
	/**
	 * Currently opened tower element market tab.
	 */
	private int currentMarket = 0;
	
	
	/**
	 * Color constraint of the four tower element markets
	 */
	private GuiQuad colorConstraintIcon[] = new GuiQuad[4];
	
	
	/**
	 * Text telling player that it's not his turn
	 */
	private GuiText notYourTurn;

	
	/**
	 * buy tower element button
	 */
	private GuiButton buyElement;
	
	
	/**
	 * Close window button
	 */
	private GuiButton close;
	
	
	/**
	 * Tower element selection from which the player can choose from.
	 */
	private GuiSelection elementSelection;
	

	/**
	 * Four parent nodes of all tower elements of the four tower element markets.
	 */
	private Node[] towerElementNode = new Node[4];
	
	
	/**
	 * Four parent nodes of all buying agents of the four tower element markets.
	 */
	private Node[] buyingAgentsNode = new Node[4];
	
	
	/**
	 * Window where the player can choose which buying agent he wants to use.
	 */
	private BuyingAgentInterface buyingAgentInterface;
	
	
	/**
	 * Number of buying agents that can be used at each of the four shops.
	 */
	private int[] numberOfBuyingAgents = {5, 4, 5, 4};
	
	
	/**
	 * List of Four lists of the current tower elements of the four markets.
	 */
	private ArrayList<ArrayList<TowerElement>> towerElements = new ArrayList<ArrayList<TowerElement>>();
	
	
	/**
	 * Array stating if all the buying agent slots have been filled.
	 */
	private boolean[] allSlotsUsed = {false, false, false, false};
	
	
	/**
	 * Constructor: Creates geometry.
	 */
	public TowerElementMarketInterface() {
		
		towerElementMarket = new Node();
		
		GuiWindow window = new GuiWindow(GUI.Offset.SCENE, 29, 30, 710, 610, 50);
		towerElementMarket.attachChild(window);
		
		GuiText title = new GuiText("Turmteil-Markt", Fonts.getLarge());
		title.setPositionSize(GUI.Offset.SCENE, (768 - (int)title.getLineWidth()) / 2, 60, 51);
		towerElementMarket.attachChild(title);
		
		GuiQuad tabsBox = new GuiQuad();
		tabsBox.setPositionSize(GUI.Offset.SCENE, 64, 105, 640, 430, 51);
		tabsBox.setMaterial(MaterialManager.getTabsBox(), 0.0f, 0.0f, 1.0f, 1.0f);
		towerElementMarket.attachChild(tabsBox.create());
		
		String[] marketTitles = {"Basisteile", "Mittelteile", "Fenster", "Spitzen"};
		
		for(int i = 0; i < 4; i++) {
			
			marketTabButtons[i] = new GuiTabButton(marketTitles[i]);
			marketTabButtons[i].setPositionSize(GUI.Offset.SCENE, 74 + (160 * i), 115, 52);
			towerElementMarket.attachChild(marketTabButtons[i].create());
			
			marketTab[i] = new Node();
			
			colorConstraintIcon[i] = new GuiQuad();
			colorConstraintIcon[i].setPositionSize(GUI.Offset.SCENE, 354, 180, 80, 30, 52);
			colorConstraintIcon[i].setMaterial(MaterialManager.getColorConstraintFlags(), 0.0f, 0.0f, 1.0f, 0.2f);
			marketTab[i].attachChild(colorConstraintIcon[i].create());
			
			towerElementNode[i] = new Node();
			marketTab[i].attachChild(towerElementNode[i]);
			
			buyingAgentsNode[i] = new Node();
			marketTab[i].attachChild(buyingAgentsNode[i]);
			
			for(int j = 0; j < numberOfBuyingAgents[i]; j++) {
				GuiSlot slot = new GuiSlot(GUI.Offset.SCENE, ((768 - (numberOfBuyingAgents[i] * 48)) / 2) + 4 + (48 * j), 345, 40, 75, 52);
				marketTab[i].attachChild(slot);
			}
			
			towerElements.add(new ArrayList<TowerElement>());
		}
		
		elementSelection = new GuiSelection(true, false);
		elementSelection.setAction(new ICallback() {
			public void run() { 
				if(elementSelection.getValue() == -1) {
					buyElement.setActive(false);
				} else {
					buyElement.setActive(true);
				}
			}
		});
		towerElementMarket.attachChild(elementSelection);
		
		marketTabButtons[0].setAction(new ICallback() { 
			public void run() { 
				displayMarket(0);
			}
		});
		
		marketTabButtons[1].setAction(new ICallback() { 
			public void run() { 
				displayMarket(1);
			}
		});
		
		marketTabButtons[2].setAction(new ICallback() { 
			public void run() { 
				displayMarket(2);
			}
		});
		
		marketTabButtons[3].setAction(new ICallback() { 
			public void run() { 
				displayMarket(3);
			}
		});
		
		elementSelection = new GuiSelection(true, false);
		
		buyElement = new GuiButton("Turmteil kaufen");
		buyElement.setPositionSize(GUI.Offset.SCENE, (768 - 220) / 2, 450, 220, 51);
		buyElement.setAction(new ICallback() { 
			public void run() {
				buyElement.setActive(false);
				close.setActive(false);
				GUI.unregisterMouseOverable(mouseOverables);
				GUI.unregisterClickable(clickables);
				GUI.unregisterMouseOverable(elementSelection.getMouseOverables());
				GUI.unregisterClickable(elementSelection.getClickables());
				
				BuyingAgent.Color colorConstraint = BuyingAgent.Color.NONE;
				
				if(currentMarket == 0) {
					colorConstraint = Game.board().getBaseElementMarket().getColorConstraint();
				} else if(currentMarket == 1) {
					colorConstraint = Game.board().getMiddleElementMarket().getColorConstraint();
				} else if(currentMarket == 2) {
					colorConstraint = Game.board().getWindowElementMarket().getColorConstraint();
				} else if(currentMarket == 3) {
					colorConstraint = Game.board().getRoofElementMarket().getColorConstraint();
				}

				if(colorConstraint == BuyingAgent.Color.NONE) {
					buyingAgentInterface = new BuyingAgentInterface(false, colorConstraint);
				} else {
					buyingAgentInterface = new BuyingAgentInterface(true, colorConstraint);
				}
				
				buyingAgentInterface.setCancelAction(new ICallback() { 
					public void run() {
						buyElement.setActive(true);
						close.setActive(true);
						GUI.registerMouseOverable(mouseOverables);
						GUI.registerClickable(clickables);
						GUI.registerMouseOverable(elementSelection.getMouseOverables());
						GUI.registerClickable(elementSelection.getClickables());
					}
				});
				buyingAgentInterface.setCarryOutActionAction(new ICallback() {
					public void run() {
						buyElement.setActive(true);
						close.setActive(true);
						GUI.registerMouseOverable(mouseOverables);
						GUI.registerClickable(clickables);
						GUI.registerMouseOverable(elementSelection.getMouseOverables());
						GUI.registerClickable(elementSelection.getClickables());
						
						int[] buyingAgentIDs = buyingAgentInterface.getBuyingAgents();
						
						boolean success = false;
						
						if(currentMarket == 0) {
							success = Game.board().getBaseElementMarket().doAction(Game.board().getMyIndex(), buyingAgentIDs[0], buyingAgentIDs[1], elementSelection.getValue());
						} else if(currentMarket == 1) {
							success = Game.board().getMiddleElementMarket().doAction(Game.board().getMyIndex(), buyingAgentIDs[0], buyingAgentIDs[1], elementSelection.getValue());
						} else if(currentMarket == 2) {
							success = Game.board().getWindowElementMarket().doAction(Game.board().getMyIndex(), buyingAgentIDs[0], buyingAgentIDs[1], elementSelection.getValue());
						} else if(currentMarket == 3) {
							success = Game.board().getRoofElementMarket().doAction(Game.board().getMyIndex(), buyingAgentIDs[0], buyingAgentIDs[1], elementSelection.getValue());
						}
						
						if(!success) {
							System.err.println("Error while executing bank action.");
							return;
						}
						GUI.changeState(GuiState.State.CLEAN_INGAME_SCREEN);
					}
				});
			}
		});
		buyElement.create();
		buyElement.setActive(false);
		
		notYourTurn = new GuiText("Du bist nicht am Zug.");
		notYourTurn.setPositionSize(GUI.Offset.SCENE, (768 - (int)notYourTurn.getLineWidth()) / 2, 459, 51);
		
		close = new GuiButton("Schliessen");
		close.setPositionSize(GUI.Offset.SCENE, (768 - 160) / 2, 555, 160, 51);
		close.setAction(new ICallback() { 
			public void run() { 
				GUI.changeState(GuiState.State.CLEAN_INGAME_SCREEN);
			}
		});
		towerElementMarket.attachChild(close.create());
		
		clickables.add(buyElement);
		clickables.add(close);
		clickables.add(marketTabButtons[0]);
		clickables.add(marketTabButtons[1]);
		clickables.add(marketTabButtons[2]);
		clickables.add(marketTabButtons[3]);
		
		mouseOverables.add(buyElement);
		mouseOverables.add(close);
		mouseOverables.add(marketTabButtons[0]);
		mouseOverables.add(marketTabButtons[1]);
		mouseOverables.add(marketTabButtons[2]);
		mouseOverables.add(marketTabButtons[3]);
		
	}
	
	
	/**
	 * Attach all needed geometry and register all mouseOver and click events.
	 */
	public void show() {
		Scenery.startCamAnimation(Location.TOWER_ELEMENT_MARKET, new ICallback() {
			public void run() {
				GUI.getTowerElementMarket().updateTowerElementMarket();

				GUI.getTowerElementMarket().displayMarket(currentMarket);
		
				GUI.getTowerElementMarket().attachChild(towerElementMarket);
				GUI.registerMouseOverable(mouseOverables);
				GUI.registerClickable(clickables);
			}
		});
	}


	/**
	 * Detach all geometry and unregister all mouseOver and click events.
	 */
	public void hide() {
		this.detachChild(towerElementMarket);
		GUI.unregisterMouseOverable(mouseOverables);
		GUI.unregisterClickable(clickables);
		Scenery.startCamAnimation(Location.BASIC_SCENE_CAMERA, null);
	}
	
	
	/**
	 * Loads the tab of a market of a specific element type.
	 */
	private void displayMarket(int market) {
		for(int i = 0; i < 4; i++) {
			if(towerElementMarket.hasChild(marketTab[i])) {
				towerElementMarket.detachChild(marketTab[i]);
			}
			if(i != market) {
				marketTabButtons[i].setActive(true);
			}
		}
		
		marketTabButtons[market].setActive(false);
		towerElementMarket.attachChild(marketTab[market]);
		
		towerElementNode[market].detachAllChildren();
		if(towerElementMarket.hasChild(elementSelection)) {
			towerElementMarket.detachChild(elementSelection);
		}
		GUI.unregisterClickable(elementSelection.getClickables());
		GUI.unregisterMouseOverable(elementSelection.getMouseOverables());
		
		buyElement.setActive(false);
		
		currentMarket = market;
		
		elementSelection = new GuiSelection(true, false);
		elementSelection.setAction(new ICallback() {
			public void run() { 
				if(elementSelection.getValue() == -1) {
					buyElement.setActive(false);
				} else {
					buyElement.setActive(true);
				}
			}
		});
		towerElementMarket.attachChild(elementSelection);
		
		int numberOfElements = towerElements.get(market).size();
		for(int i = 0; i < numberOfElements; i++) {
			
			TowerElement element = towerElements.get(market).get(i);
			
			elementSelection.addOption(element.getId(), GUI.Offset.SCENE, ((768 - (70 * numberOfElements)) / 2) + 5 + (70 * i), 230, 60, 60, 52);
				
			GuiTowerElement guiElement = new GuiTowerElement(element);
			towerElementNode[market].attachChild(guiElement.get2D(GUI.Offset.SCENE, ((768 - (70 * numberOfElements)) / 2) + 35 + (70 * i), 273, 53, 1.0f));
			
			GuiText cost = new GuiText(Integer.toString(element.getCost()));
			cost.setPositionSize(GUI.Offset.SCENE, ((768 - (70 * numberOfElements)) / 2) + 46 + (70 * i), 300, 53);
			towerElementNode[market].attachChild(cost);
			
			GuiQuad coin = new GuiQuad();
			coin.setPositionSize(GUI.Offset.SCENE, ((768 - (70 * numberOfElements)) / 2) + 8 + (70 * i), 290, 40, 40, 53);
			coin.setMaterial(MaterialManager.getPanelIcons(), 0.0f, 0.5f, 0.5f, 0.5f);
			towerElementNode[market].attachChild(coin.create());
		}
		
		if(Game.board().getTurn() == Game.board().getMyIndex() && !allSlotsUsed[currentMarket]) {
			elementSelection.activateAll();
			int playerMoney = Game.board().me().getMoneyBalance();
			ArrayList<TowerElement> currentTowerElement = towerElements.get(currentMarket);
			for(int i = 0; i < currentTowerElement.size(); i++) {
				if(currentTowerElement.get(i).getCost() > playerMoney) {
					elementSelection.deactivate(currentTowerElement.get(i).getId());
				}
			}
		} else {
			elementSelection.deactivateAll();
		}
		
		GUI.registerClickable(elementSelection.getClickables());
		GUI.registerMouseOverable(elementSelection.getMouseOverables());

	}


	/**
	 * Updates tower element market selection and buying agent slots.
	 */
	public void updateTowerElementMarket() {
		
		elementSelection.clearSelection();
		
		towerElements.get(0).clear();
		towerElements.get(0).addAll(Game.board().getBaseElementMarket().getTowerElementSelection());
		towerElements.get(1).clear();
		towerElements.get(1).addAll(Game.board().getMiddleElementMarket().getTowerElementSelection());
		towerElements.get(2).clear();
		towerElements.get(2).addAll(Game.board().getWindowElementMarket().getTowerElementSelection());
		towerElements.get(3).clear();
		towerElements.get(3).addAll(Game.board().getRoofElementMarket().getTowerElementSelection());
		
		for(int i = 0; i < 4; i++) {
			
			BuyingAgent.Color colorConstraint = BuyingAgent.Color.NONE;
			int[] useOfSlots = {};
			
			if(i == 0) {
				colorConstraint = Game.board().getBaseElementMarket().getColorConstraint();
				useOfSlots = Game.board().getBaseElementMarket().getBuyingAgentSlots();
			} else if(i == 1) {
				colorConstraint = Game.board().getMiddleElementMarket().getColorConstraint();
				useOfSlots = Game.board().getMiddleElementMarket().getBuyingAgentSlots();
			} else if(i == 2) {
				colorConstraint = Game.board().getWindowElementMarket().getColorConstraint();
				useOfSlots = Game.board().getWindowElementMarket().getBuyingAgentSlots();
			} else if(i == 3) {
				colorConstraint = Game.board().getRoofElementMarket().getColorConstraint();
				useOfSlots = Game.board().getRoofElementMarket().getBuyingAgentSlots();
			}
			
			allSlotsUsed[i] = (useOfSlots[numberOfBuyingAgents[i] - 1] != 0);
			
			if(colorConstraint == BuyingAgent.Color.NONE && marketTab[i].hasChild(colorConstraintIcon[i])) {
				marketTab[i].detachChild(colorConstraintIcon[i]);
			}
			if(colorConstraint != BuyingAgent.Color.NONE && !marketTab[i].hasChild(colorConstraintIcon[i])) {
				marketTab[i].attachChild(colorConstraintIcon[i]);
			}
			
			if(colorConstraint == BuyingAgent.Color.BLUE) {
				colorConstraintIcon[i].changeTextureCoords(0.0f, 0.0f, 1.0f, 0.2f);
			} else if(colorConstraint == BuyingAgent.Color.GREEN) {
				colorConstraintIcon[i].changeTextureCoords(0.0f, 0.2f, 1.0f, 0.2f);
			} else if(colorConstraint == BuyingAgent.Color.ORANGE) {
				colorConstraintIcon[i].changeTextureCoords(0.0f, 0.4f, 1.0f, 0.2f);
			} else if(colorConstraint == BuyingAgent.Color.PURPLE) {
				colorConstraintIcon[i].changeTextureCoords(0.0f, 0.6f, 1.0f, 0.2f);
			} else if(colorConstraint == BuyingAgent.Color.YELLOW) {
				colorConstraintIcon[i].changeTextureCoords(0.0f, 0.8f, 1.0f, 0.2f);
			}
		
			
			buyingAgentsNode[i].detachAllChildren();
		
			for(int j = 0; j < numberOfBuyingAgents[i]; j++) {
				if(useOfSlots[j] == 1) {
					buyingAgentsNode[i].attachChild(GuiBuyingAgent.getColor2D(colorConstraint, GUI.Offset.SCENE, ((768 - (numberOfBuyingAgents[i] * 48)) / 2) + 4 + (48 * j), 345, 53));
				} else if(useOfSlots[j] == 2) {
					buyingAgentsNode[i].attachChild(GuiBuyingAgent.getColor2D(BuyingAgent.Color.NONE, GUI.Offset.SCENE, ((768 - (numberOfBuyingAgents[i] * 48)) / 2) + 4 + (48 * j), 345, 53));
				}
			}
		}
		
		if(Game.board().getTurn() == Game.board().getMyIndex()) {
			if(towerElementMarket.hasChild(notYourTurn)) {
				towerElementMarket.detachChild(notYourTurn);
			}
			if(!towerElementMarket.hasChild(buyElement)) {
				towerElementMarket.attachChild(buyElement);
			}

		} else {
			if(!towerElementMarket.hasChild(notYourTurn)) {
				towerElementMarket.attachChild(notYourTurn);
			}
			if(towerElementMarket.hasChild(buyElement)) {
				towerElementMarket.detachChild(buyElement);
			}
		}
		displayMarket(currentMarket);
	}
	
}
